package com.theyeasy.dvmini.weixin.controller;

import java.io.PrintWriter;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;
import org.theyeasy.weixin.service.WxOpenMpService;
import org.theyeasy.weixin.service.WxOpenService;
import org.theyeasy.weixin.util.WXBizMsgCrypt;
import org.theyeasy.weixin.util.WxMessageUtil;
import org.theyeasy.weixin.util.WxMpUtil;

import tk.mybatis.mapper.entity.Example;

import com.theyeasy.dvmini.dao.SalesDao;
import com.theyeasy.dvmini.model.Sales;
import com.theyeasy.dvmini.pc.controller.BaseController;
import com.theyeasy.dvmini.service.PosterService;
import com.theyeasy.dvmini.service.SalesService;
import com.theyeasy.dvmini.service.SysWxauthorizeService;
import com.theyeasy.dvmini.util.CommonUtil;
import com.theyeasy.dvmini.util.RedisUtil;
import com.theyeasy.dvmini.vo.Vo_msg;

import me.chanjar.weixin.common.exception.WxErrorException;
import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage;
import me.chanjar.weixin.mp.bean.message.WxMpXmlOutMessage;
import me.chanjar.weixin.mp.bean.result.WxMpOAuth2AccessToken;

@Controller
@RequestMapping("/wx")
public class WxController extends BaseController {
	@Autowired
	WxOpenService wxOpenService;

	WxOpenMpService WxOpenMpService;
	@Autowired
	SysWxauthorizeService sysWxauthorizeService;

	@Autowired
	SalesService salesService;

	@Autowired
	PosterService posterService;

	@Autowired
	SalesDao saleDao;

	/*
	 * 授权回调，获取授权公众号
	 */
	@RequestMapping(value = "getAuthAuthorization", method = RequestMethod.POST)
	@ResponseBody
	public Vo_msg getAuthAuthorization(HttpServletRequest request, @RequestParam(value = "auth_code") String auth_code, @RequestParam(value = "merchantId", required = true) Integer merchantId) {
		try {
			String msg = wxOpenService.getApiGetAuthorizerInfo(auth_code, merchantId);
			return new Vo_msg(0, "", msg);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return new Vo_msg(-1, "", e.getLocalizedMessage());
		}

	}

	private final static String COMPONENT_VERIFY_TICKET = "component_verify_ticket";

	// 接收微信每十分钟推送一次的授权ticket
	@RequestMapping(value = "authorize")
	public void acceptAuthrizeTicket(HttpServletRequest request, HttpServletResponse response, @RequestParam(value = "msg_signature") String msg_signature, @RequestParam(value = "timestamp") String timestamp, @RequestParam(value = "nonce") String nonce) throws Exception {
		try {

			System.out.println("收到ticket推送：signature=" + msg_signature + "   timestamp=" + timestamp + " nonce=" + nonce);

			String data = WxMessageUtil.readStrFromInputStream(request);
			Map<String, String> map = WxMessageUtil.parseXml(data);
			String appid = map.get("AppId");
			String encrypt = map.get("Encrypt");
			String openToken = wxOpenService.getWxOpenConfigStorage().getToken();
			String aseKey = wxOpenService.getWxOpenConfigStorage().getAesKey();
			System.out.println("openToken=" + openToken + "   aseKey=" + aseKey);
			WXBizMsgCrypt wxBizMsgCrypt = new WXBizMsgCrypt(openToken, aseKey, appid);
			// 得到解密后的消息内容
			String decrpytMsg = wxBizMsgCrypt.decryptMsg(msg_signature, timestamp, nonce, encrypt);
			Map<String, String> decryptMap = WxMessageUtil.parseXml(decrpytMsg);

			if (null != decryptMap && decryptMap.containsKey("InfoType")) {
				if (COMPONENT_VERIFY_TICKET.equals(decryptMap.get("InfoType").toLowerCase())) {
					String verifyTicket = decryptMap.get("ComponentVerifyTicket");
					CommonUtil.sendWeiXinTicket(appid, verifyTicket); // 发送到托管服务器

					wxOpenService.getWxOpenConfigStorage().updateComponentVerifyTicket(verifyTicket);// 更新本地缓存变量

				}
			}

			PrintWriter writer = response.getWriter();
			writer.print("success");
			writer.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	// 接收公众号的事件消息
	@RequestMapping(value = "/{APPID}/msg")
	public void msg(HttpServletRequest request, HttpServletResponse response, @PathVariable("APPID") String appid, @RequestParam(value = "msg_signature") String msg_signature, @RequestParam(value = "timestamp") String timestamp, @RequestParam(value = "nonce") String nonce) throws Exception {
		response.setCharacterEncoding("utf-8");
		String msg = "success";
		
		 
		try {

			String data = WxMessageUtil.readStrFromInputStream(request);
			Map<String, String> map = WxMessageUtil.parseXml(data);
			String encrypt = map.get("Encrypt");

			String openToken = wxOpenService.getWxOpenConfigStorage().getToken();
			String aseKey = wxOpenService.getWxOpenConfigStorage().getAesKey();
			String openAppId = wxOpenService.getWxOpenConfigStorage().getAppId();

			WXBizMsgCrypt wxBizMsgCrypt = new WXBizMsgCrypt(openToken, aseKey, openAppId);

			try {
				wxOpenService.getWxMpService(appid);
			} catch (Exception e) {
				wxOpenService.initWxMpService(appid, "");// 注册
			}
			String decrypt = wxBizMsgCrypt.decryptMsg(msg_signature, timestamp, nonce, encrypt);
			 
			WxMpXmlMessage inMessage = WxMpXmlMessage.fromXml(decrypt);
			WxMpXmlOutMessage outMessage = wxOpenService.route(inMessage, appid);
			if (null != outMessage) msg = wxBizMsgCrypt.encryptMsg(outMessage.toXml(), timestamp, nonce);
		} catch (Exception e) {
			e.printStackTrace();
		}

		PrintWriter writer = response.getWriter();
		writer.print(msg);
		writer.close();
	}

	/* 销售人员绑定身份 */
	@RequestMapping(value = "/regist")
	public ModelAndView regist(Map<String, Object> model, @RequestParam(value = "code", required = false) String code, @RequestParam(value = "state", required = false) String state) {
		model.put("wxMiniCode", state);// state中传入小程序的openid
		model.put("wxCode", code);
		// 判断是否已绑定
		String linkurl = salesService.CheckBinding(state);
		model.put("linkurl", linkurl);
		ModelAndView view = new ModelAndView("/weixin/binding", model);
		return view;
	}

	@RequestMapping(value = "/doRegist", method = RequestMethod.GET)
	@ResponseBody
	public Object doRegist(@RequestParam(value = "wxMiniCode") String wxMiniCode, @RequestParam(value = "wxCode") String wxCode, @RequestParam(value = "phone") String phone) {
		String msg = "绑定成功";
		try {
			System.out.println("进入绑定");
			WxMpOAuth2AccessToken accessToken = wxOpenService.getWxMpService(RedisUtil.getMpAppid()).oauth2getAccessToken(wxCode);
			String openId = accessToken.getOpenId();
			Vo_msg vo_msg = salesService.updateSalesOpenId(phone, openId, wxMiniCode);
			return vo_msg;

		} catch (Exception e) {
			e.printStackTrace();
			msg = "绑定失败,accesstoken异常";
		}
		return new Vo_msg(-1, null, msg);
	}

	@RequestMapping(value = "/chatListView")
	public ModelAndView chatListView(@RequestParam("salesId") Integer salesId, @RequestParam("code") String code, Map<String, Object> model) {
		WxMpOAuth2AccessToken accessToken;
		String openId = "";
		try {
			if (code.equals("nmamtf18565803458")) {
				Sales sale = saleDao.selectByPrimaryKey(salesId);
				model.put("salesId", sale.getId());
				model.put("isVanker", sale.getIsvanker());
				return new ModelAndView("/weixin/chat", model);
			}

			accessToken = wxOpenService.getWxMpService(RedisUtil.getMpAppid()).oauth2getAccessToken(code);
			openId = accessToken.getOpenId();
			Sales sale = saleDao.selectByPrimaryKey(salesId);

			// add by lcc 171110,打日志跟踪销售无法登录的问题。
			if (sale != null) {
				logger.info("销售[" + sale.getName() + "]登录：code->openid=" + openId + ", sale.openid=" + sale.getWxopenid());
			} else {
				logger.info("销售登录：id不存在,id=" + salesId);
			}

			if (sale != null && sale.getWxopenid().equals(openId)) {
				model.put("salesId", sale.getId());
				model.put("isVanker", sale.getIsvanker());
				return new ModelAndView("/weixin/chat", model);
			}
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		model.put("message", "访问失败!(请用销售本人微信访问该链接),openid=" + openId);
		return new ModelAndView("/weixin/error", model);
	}

}
